using System;
using System.IO;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using DE.Sdc.SharePoint.SPContentStructure.Common;

namespace DE.Sdc.SharePoint.SPContentStructure.Import
{
    [Serializable]
    [XmlType(AnonymousType = true, Namespace = DeploymentConstants.Namespace)]
    [XmlRoot(Namespace = DeploymentConstants.Namespace, IsNullable = false)]
    public abstract class BaseFile<TParent> : HierarchicalElement<TParent>, IBaseFile<TParent> where TParent : IBaseItem
    {    
        /// <remarks/>
        [XmlIgnore]
        public Item Item { get; set; }

        /// <remarks/>
        [XmlAttribute]
        public FileActionType FileAction { get; set; }

        [XmlAttribute]
        public virtual string Path { get; set; }

        /// <remarks/>
        [XmlAttribute]
        public bool OverwriteFileTitleWithItemTitle { get; set; }

        

        [XmlAttribute]
        public int Version { get; set; }

        protected abstract bool IsNewVersion(object sharePointObject);

        protected abstract void SetNewVersion(object sharePointObject);

        /// <summary>
        /// Delivers a string with the absolute feature related path to a given filename within the feature
        /// </summary>
        /// <param name="file">A filename from a file within the feature</param>
        /// <returns>A string with the absolute path</returns>
        internal static string GetFeatureRootedPath(string file)
        {
            if (System.IO.Path.IsPathRooted(file))
                return file;

            if (DeploymentContext.Current.ReceiverProperties != null)
                return System.IO.Path.Combine(DeploymentContext.Current.ReceiverProperties.Definition.RootDirectory, file);

            return System.IO.Path.Combine(DeploymentContext.Current.ImportPath, file);
        }

        public void ChangeFileLevel(SPFile file, IBaseItem baseItem)
        {
            if (FileAction >= FileActionType.UndoCheckOut &&
                    file.Level == SPFileLevel.Checkout)
            {

#if SP_07
            if (file.CheckedOutBy != null &&
                                file.CheckedOutBy.LoginName != DeploymentContext.Current.ReceiverWeb.CurrentUser.LoginName)
                                file.UndoCheckOut();
#else
                if (file.CheckedOutByUser != null &&
                    file.CheckedOutByUser.LoginName != DeploymentContext.Current.ReceiverWeb.CurrentUser.LoginName)
                    file.UndoCheckOut();
#endif

                
            }

            if (FileAction >= FileActionType.CheckIn &&
                    file.Level == SPFileLevel.Checkout)
            {
                if ((FileAction >= FileActionType.Publish) && (file.Item.ParentList.EnableMinorVersions))
                    file.CheckIn("", SPCheckinType.MajorCheckIn);
                else
                    file.CheckIn("");
            }
            else
            {
                if (file.Level == SPFileLevel.Draft && file.Item.ParentList.EnableMinorVersions)
                    file.Publish("");
            }

            System.Collections.Hashtable properties = null;
            if (file.Name != "default.aspx" && (file.Item != null) && (baseItem != null) && (baseItem.Properties != null))
            {
                properties = baseItem.Properties.GetAsHashtable(null);
                var updated = false;
                if (properties.ContainsKey("Editor"))
                {
                    updated |= ItemProperties.SetPropertyValue(file.Item, "Editor", properties["Editor"]);
                }
                if (updated)
                    file.Item.UpdateOverwriteVersion();
            }

            if ((FileAction == FileActionType.Approve) && (file.Item != null) && file.Item.ParentList.EnableModeration)
            {
                //Removed the !file.Item.ParentList.EnableMinorVersions check in the if condition.
                //When this check was present, importing content in libraries with enabled moderation
                //and enabled minor versioning (for example the master page gallery) left the imported
                //items in status "Draft"
                if (file.Level == SPFileLevel.Published ||
                    file.Level == SPFileLevel.Draft)
                    file.Approve("");
            }

            if (file.Name != "default.aspx" && (file.Item != null) && (baseItem != null) && (baseItem.Properties != null))
            {
                if (properties == null)
                    properties = baseItem.Properties.GetAsHashtable(null);
                var updated = false;
                if (properties.ContainsKey("Modified"))
                {
                    updated |= ItemProperties.SetPropertyValue(file.Item, "Modified", properties["Modified"]);
                }
                if (updated)
                    file.Item.SystemUpdate(false);
            }
        }

        public void Checkout(SPFile file)
        {
            if ((file == null) || (file.Exists == false) || ((Item != null) && (Item.List == null)))
                return;

            UndoCheckout(file);

            #if SP_07
                        if (file.CheckedOutBy == null)
                            file.CheckOut();
            #else
               if (file.CheckedOutByUser == null)
                        file.CheckOut();
            #endif

        }

        public void UndoCheckout(SPFile file)
        {
            bool undoCheckout = false;

            if (Item != null && Item.List != null)
                undoCheckout = Item.List.UndoFileCheckout;

            undoCheckout &= FileAction == FileActionType.UndoCheckOut;
#if SP_07
 if (undoCheckout && file.CheckedOutBy != null &&
                            file.CheckedOutBy.LoginName == DeploymentContext.Current.ReceiverWeb.CurrentUser.LoginName)
                file.UndoCheckOut();
#else
 if (undoCheckout && file.CheckedOutByUser != null &&
                file.CheckedOutByUser.LoginName == DeploymentContext.Current.ReceiverWeb.CurrentUser.LoginName)
             file.UndoCheckOut();
#endif


        }
    }
}